package ch7.ex13;

import static ch7.print.Print.*;

public class ReferenceCounting {
	public static void main(String... args){
		Shared s = new Shared();
		Composing[] c = {new Composing(s),
						 new Composing(s),
						 new Composing(s),
						 new Composing(s)};
		for(Composing cc:c)
			cc.dispose();
		
		System.gc();
		new Composing(new Shared());
		System.gc();
	}
}

class Shared{
	private int refcount = 0;
	private static long counter = 0;
	private static long id = counter++;
	
	public Shared(){
		println("Creating " + this);
	}
	public void addRef(){
		refcount++;
	}
	protected void dispose(){
		if(--refcount == 0)
			println("Disposing " + this);
	}
	protected void finalize(){
		if(refcount != 0){
			println("Error: object is not properly cleand-up");
		}
	}
	public String toString(){
		return "Shared " + id;
	}
}

class Composing{
	private Shared shared;
	private static long counter = 0;
	private final long id = counter++;
	public Composing(Shared shared){
		println("Creating " + this);
		this.shared = shared;
		this.shared.addRef();
	}
	protected void dispose(){
		println("disposing " + this);
		shared.dispose();
	}
	public String toString(){
		return "Composing " + id;
	}
}